import { MSG_TYPES } from './utils/MESSAGE_TYPES'
import TaskQueue from './utils/bgActionQueue'
/**
 * 请求生命周期
 * msg open -> 创建
 * msg send -> 发送
 * xhr response -> 相应销毁
 */
console.log('background')
// 监听 content_script 的send_message  现在主要是受理一下get storage的请求，获取chrome：extention的localstorage
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.event === MSG_TYPES.matchingReq) {
        sendResponse(JSON.parse(localStorage.getItem('PROXY_ROUTES')))
    }
})

/**
 * 请求列表
 */
const REQUEST_MAP = {}

const queue = new TaskQueue()
queue.start()

chrome.extension.onConnect.addListener(function (port) {
    port.onMessage.addListener(function (msg, b, c) {
        if (!msg.event) {
            return
        }
        switch (msg.event) {
            case MSG_TYPES.setProps: {
                const task = async function () {
                    const { prop, value } = msg.data
                    console.log('set', prop, value)
                    const xhr = REQUEST_MAP[msg.id]
                    xhr[prop] = value
                }
                queue.pushTask(task)
            } break
            case MSG_TYPES.open: {
                const task = async function () {
                    const xhr = new XMLHttpRequest()
                    const {
                        method,
                        url,
                        async,
                        user,
                        password
                    } = msg.data
                    xhr.open(method, url, async, user, password)
                    REQUEST_MAP[msg.id] = xhr
                }
                queue.unShiftTask(task)
            } break
            case MSG_TYPES.send: {
                const task = async function () {
                    const xhr = REQUEST_MAP[msg.id]
                    const { body } = msg.data
                    xhr.onreadystatechange = async function () {
                        if (xhr.readyState === XMLHttpRequest.DONE) {
                            // 同步
                            const {
                                readyState,
                                response,
                                responseType,
                                responseURL,
                                status,
                                statusText
                            } = xhr
                            var headers = xhr.getAllResponseHeaders();
                            port.postMessage({
                                event: MSG_TYPES.response,
                                id: msg.id,
                                headers,
                                data: {
                                    readyState,
                                    response: responseType === 'blob' ? await blobToDataURL(new Blob([response])) : response,
                                    ...(
                                        responseType === ''
                                            ? {
                                                responseText: xhr.responseText,
                                                responseXML: xhr.responseXML
                                            }
                                            : responseType === 'text'
                                                ? {
                                                    responseText: xhr.responseText
                                                }
                                                : responseType === 'document'
                                                    ? {
                                                        responseXML: xhr.responseXML
                                                    } : {}
                                    ),
                                    responseType,
                                    responseURL,
                                    status,
                                    statusText
                                }
                            })
                            delete REQUEST_MAP[msg.id]
                        }
                    }
                    xhr.send(body)
                }
                queue.pushTask(task)
            } break
            case MSG_TYPES.setRequestHeader: {
                const task = async function () {
                    const xhr = REQUEST_MAP[msg.id]
                    const { header, value } = msg.data
                    xhr.setRequestHeader(header, value)
                }
                queue.pushTask(task)
            } break
            default:
                break;
        }
    });
});

async function blobToDataURL(blob) {
    return new Promise(resolve => {
        let a = new FileReader();
        a.onload = function (e) { resolve(e.target.result); }
        a.readAsDataURL(blob);
    })
}
